#include "mytcpsocket.h"
#include <string>
#include <QDebug>
#include <QDataStream>
#define MAX_BODY_SIZE 1024
using std::string;

MyTcpSocket::MyTcpSocket(QObject *parent):
    m_timeoutTimer(new QTimer(this))
{
    setParent(parent);
    connect(this, &MyTcpSocket::readyRead, this, &MyTcpSocket::readPacket);
    // connect(m_qTcpSocket,&QTcpSocket::readyRead,this,&MyTcpSocket::readPacket);
}

void MyTcpSocket::sendTLV(TaskType type, int len, const char *msg)
{
    TLV tlv;
    tlv._type = type;
    tlv._length = len;
    memcpy(tlv._data, msg, len); // 这里不能用strcpy，因为msg中间可能有'\0'
    if (tlv._length > 0) {
        write((const char *)&tlv, sizeof(int) + sizeof(int) + tlv._length);
    }
}

void MyTcpSocket::readPacket()
{
    qDebug()<<"开始读取接受的数据";
    // 循环处理，直到没有完整数据包可用
    while (true) {
        if (m_expectedBodySize == 0) {//如果期待数据为0，说明还没开始读到长度字符串
            // 阶段1: 等待并读取头部 (两个int，共8字节)
           // qDebug()<<"目前有"<<bytesAvailable()<<"可读";
            if (bytesAvailable() < 8) {
                return; // 头部数据不完整，等待下次数据到达
            }

            // 读取头部
            read((char*)&m_packet._type, sizeof (int));
            read((char*)&m_packet._length, sizeof (int));
            // in.setVersion(QDataStream::Qt_5_15); // 设置合适的版本

            qDebug()<<"type " << m_packet._type<<endl;
            qDebug()<<"length " << m_packet._length<<endl;

            m_expectedBodySize = m_packet._length;//设置数据长度为TLV.length

            // 可选：验证数据长度是否合理
            if (m_expectedBodySize < 0 || m_expectedBodySize > MAX_BODY_SIZE) {
                // 处理错误：无效的数据长度
                abort();
                return;
            }
        }
        // 阶段2: 检查是否有足够的数据体
        if (bytesAvailable() < m_expectedBodySize) {
            return; // 数据体不完整，等待下次数据到达
        }
        // 阶段3: 读取完整的数据体
        m_packet._msg = read(m_expectedBodySize);
        qDebug()<<"msg" <<m_packet._msg<<endl;
        emit readPacketFinished(m_packet);//发射读取完成信号，传出读取完成的packdet，交给应用层处理
        // 重置状态，准备处理下一个消息
        clear();
    }
}

void MyTcpSocket::clear(){
    m_expectedBodySize = 0;
    m_recvTLV.clear();
    m_packet.clear();
}


